package com.mega.center.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.mega.center.system.mapper.ModuleMapper;
import com.mega.center.system.model.entity.Module;
import com.mega.center.system.service.IModuleService;
import com.mega.common.core.constant.Constants;
import com.mega.common.core.constant.UserConstants;
import com.mega.common.core.enums.CommonMsgEnum;
import com.mega.common.core.enums.CommonStatus;
import com.mega.common.core.exception.BusinessException;
import com.mega.common.core.web.service.MegaBaseServiceImpl;
import com.mega.common.redis.utils.CodeUtils;
import com.mega.common.security.utils.SecurityUtils;
import com.mega.system.api.vo.ModuleVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 系统模块  服务实现
 *
 * @author Eric
 * @version 1.0
 * @since 2020-09-24
 */
@Service
public class ModuleServiceImpl extends MegaBaseServiceImpl<ModuleMapper, Module> implements IModuleService {

    /**
     * 新增系统模块
     *
     * @param module 系统模块 实体类
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(Module module) {
        String parentCode = StrUtil.isBlank(module.getParentModuleCode()) ? UserConstants.DEFAULT_TREE_ROOT_CODE : module.getParentModuleCode();
        Integer nameCount = this.count(Wrappers.<Module>lambdaQuery()
                .eq(Module::getParentModuleCode, parentCode)
                .eq(Module::getModuleName, module.getModuleName()));
        if (nameCount != null && nameCount > 0) {
            throw new BusinessException(CommonMsgEnum.NAME_REPEAT, module.getModuleName());
        }
        module.setStatus(CommonStatus.NORMAL.getCode());
        module.setModuleCode(CodeUtils.getDateCode(module));
        //设置父节点编码
        Module parentModule = getModuleByCode(parentCode);
        module.setParentModuleCode(parentCode);
        module.setParentModuleCodes((StrUtil.isBlank(parentModule.getParentModuleCodes()) ? "" : parentModule.getParentModuleCodes()) + parentCode + Constants.COMMA_SEPARATOR);
        module.setTreeLevel(parentModule.getTreeLevel() + 1);
        //插入数据
        this.save(module);
    }

    /**
     * 根据编码获取模块信息
     *
     * @param code
     * @return
     */
    @Override
    public Module getModuleByCode(String code) {
        if (UserConstants.DEFAULT_TREE_ROOT_CODE.equals(code)) {
            Module module = new Module();
            module.setModuleCode(UserConstants.DEFAULT_TREE_ROOT_CODE);
            module.setModuleName("ROOT");
            module.setTreeLevel(0);
            return module;
        } else {
            return this.getOne(Wrappers.<Module>lambdaQuery()
                    .eq(Module::getModuleCode, code));
        }
    }

    /**
     * 编辑系统模块
     *
     * @param module 系统模块 实体类
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Module module) {
        //判断数据是否为空
        Module queryEntity = this.getById(module.getId());
        if (queryEntity == null) {
            throw new BusinessException(CommonMsgEnum.DATE_NOT_EXIST);
        }
        //查询修改后名称是否与原先一致
        if (!module.getModuleName().equals(queryEntity.getModuleName())) {
            //判断名称是否重复
            Integer nameCount = this.count(Wrappers.<Module>lambdaQuery()
                    .eq(Module::getParentModuleCode, module.getParentModuleCode())
                    .eq(Module::getModuleName, module.getModuleName()));
            if (nameCount != null && nameCount > 0) {
                throw new BusinessException(CommonMsgEnum.NAME_REPEAT, module.getModuleName());
            }
        }
        //判断是否变更上级
        String parentCode = StrUtil.isBlank(module.getParentModuleCode()) ? UserConstants.DEFAULT_TREE_ROOT_CODE : module.getParentModuleCode();
        if (!parentCode.equals(queryEntity.getParentModuleCode())) {
            Module parentMenu = getModuleByCode(parentCode);
            String newParentCodes = (StrUtil.isBlank(parentMenu.getParentModuleCodes()) ? "" : parentMenu.getParentModuleCodes()) + parentCode + Constants.COMMA_SEPARATOR;
            String oldChildParentCodes = queryEntity.getParentModuleCodes() + queryEntity.getModuleCode() + Constants.COMMA_SEPARATOR;
            String newChildParentCodes = newParentCodes + queryEntity.getModuleCode() + Constants.COMMA_SEPARATOR;
            int oldLevel = queryEntity.getTreeLevel();
            int newLevel = parentMenu.getTreeLevel() + 1;
            //变更子节点父节点集合
            List<Module> childs = this.list(Wrappers.<Module>lambdaQuery().likeRight(Module::getParentModuleCodes, oldChildParentCodes));
            if (CollectionUtil.isNotEmpty(childs)) {
                childs.forEach(v -> {
                    v.setParentModuleCodes(v.getParentModuleCodes().replace(oldChildParentCodes, newChildParentCodes));
                    v.setTreeLevel(v.getTreeLevel() + newLevel - oldLevel);
                });
                this.updateBatchById(childs);
            }
            module.setParentModuleCode(parentCode);
            module.setParentModuleCodes(newParentCodes);
            module.setTreeLevel(newLevel);
        }

        //更新数据
        this.updateById(module);
    }

    /**
     * 根据id删除系统模块
     *
     * @param id 主键值
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(Integer id) {
        this.removeById(id);
    }

    /**
     * 查询子系统列表：层级为1的数据
     *
     * @return
     */
    @Override
    public List<ModuleVO> listSystemModule() {
        return this.baseMapper.listSystemModule(CommonStatus.NORMAL.getCode());
    }

    /**
     * 修改模块状态
     *
     * @param id
     * @param status
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeModuleStatus(Long id, String status) {
        if (!status.equals(CommonStatus.NORMAL.getCode())
                && !status.equals(CommonStatus.DISABLED.getCode())) {
            throw new BusinessException(CommonMsgEnum.STATUS_NOT_VALID, status);
        }

        Module module = new Module();
        module.setId(id);
        module.setStatus(status);
        this.baseMapper.updateById(module);
    }

    /**
     * 获取用户拥有的模块
     *
     * @param userName
     * @return
     */
    @Override
    public List<ModuleVO> listUserModule(String userName) {
        if (SecurityUtils.isAdmin(userName)) {
            return this.listSystemModule();
        } else {
            return this.baseMapper.listUserModule(userName);
        }
    }
}
